/**
 * @ComponentScan 默认扫描同包或子包下的 Controller，如果扫描非同包或子包下的 Controller 则需要通过 basePackages 指定
 * @EntityScan 扫描指定包下的实体类
 * @EnableJpaRepositories 启用 JPA 库
 */

package com.artup.start;

import java.io.File;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.PlatformTransactionManager;

import com.artup.service.impl.ThreadExecutorService;
import com.artup.util.SpringContextUtils;
import com.artup.util.file.PropertiesUtils;
import com.artup.util.http.HttpClientUtil;
import com.artup.util.http.HttpConnectionManager;

/**
 * 启动入口
 * @author hapday
 * @date 2017年7月13日 @Time 下午3:55:24
 */
@Configuration
@EntityScan( basePackages = { "com.artup.domain" } )
@ComponentScan( basePackages = { "com.artup.controller", "com.artup.service", "com.artup.dao" } )
@EnableJpaRepositories( basePackages = { "com.artup.repository" } )
@EnableAutoConfiguration
@SpringBootApplication
@MapperScan( basePackages = "com.artup.dao" )		// 指定 *Dao.java 所在的包
@EnableAsync // 开启异步任务支持  
public class Application extends SpringBootServletInitializer {
	protected static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
	
	public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
	
	@Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
	
	/**
	 * 获取数据源
	 * @return
	 */
	@Bean
	@ConfigurationProperties( prefix = "spring.datasource" )
	public DataSource getDataSource() {
		return new DataSource();
	}
	
	@Bean
	public SqlSessionFactory getSqlSessionFactoryBean() throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(this.getDataSource());		// 设置数据源
		
		PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
		sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:/mapper/*.xml"));		// 指定 *Mapper.xml 文件所在的文件夹
		
		return sqlSessionFactoryBean.getObject();
	}
	
	@Bean
	public PlatformTransactionManager getTranactionManager() {
		return new DataSourceTransactionManager(this.getDataSource());
	}
	
	@Bean
	public SpringContextUtils getSpringContextUtils() {
		return new SpringContextUtils();
	}
	
	/*
	 * 
	@Bean
	public RegionCache loadRegionCache(){
		return RegionCache.getInstanceByLoad();
	}*/
	
	/*@Bean
	public CacheLoad getCacheLoad() {
		List<Class<RegionCache>> regionList = new ArrayList<Class<RegionCache>>();
		regionList.add(RegionCache.class);
		
		return new CacheLoad(regionList);
	}*/
	
	@Bean(name = "threadExecutorService", initMethod = "init", destroyMethod = "shutdown")
	@ConditionalOnMissingBean(value = ThreadExecutorService.class)
	public ThreadExecutorService threadExecutorService() {
		return new ThreadExecutorService();
	}

	@Bean( name = "httpConnectionManager", initMethod = "init" )
	public HttpConnectionManager getHttpConnectionManager() {
		return new HttpConnectionManager();
	}

	@Bean( name = "httpClientUtil" )
	public HttpClientUtil getHttpClientUtil() {
		return new HttpClientUtil();
	}
	
	@Bean
	public String initSystem(){
		String isinitializeFilePermission = PropertiesUtils.getValue("system.initialize.filePermission");
		
		if(StringUtils.isBlank(isinitializeFilePermission)) {
			return "FAILURE";
		}
		
		if(!Boolean.parseBoolean(isinitializeFilePermission)){
			return "FAILURE";
		}
		
		String contextPath = PropertiesUtils.getValue("system.context.path") + File.separator;
		
		ApplicationUtil applicationUtil = new ApplicationUtil();
		applicationUtil.initFilePermission(contextPath);
		
		return "SUCCESS";
	}
}
